package cn.zl.common.manage;

import cn.hutool.core.util.ObjUtil;
import cn.zl.ZLM.core.ZLMApi;
import cn.zl.ZLM.event.callback.impl.MKProxyPlayerCallBack;
import cn.zl.ZLM.event.callback.inter.IMKProxyPlayerCallBack;
import cn.zl.ZLM.helper.ZLMApiHelper;
import cn.zl.ZLM.structure.MK_INI;
import cn.zl.ZLM.structure.MK_PROXY_PLAYER;
import cn.zl.common.manage.data.StreamProxyData;
import cn.zl.model.StreamProxy;
import com.sun.jna.Pointer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Component
public class StreamProxyManage {

    private static final Logger logger = LoggerFactory.getLogger(StreamProxyManage.class);

    private final Map<String, StreamProxyData> manage = new HashMap<>();

    public void start(StreamProxy proxy) {
        StreamProxyData data = manage.get(proxy.getProxyId());
        if (ObjUtil.isNotNull(data)) {
            logger.info("[开启-拉流代理] 已经存在 proxy_id:{} app: {} stream: {}", proxy.getProxyId(), proxy.getApp(), proxy.getStream());
            return;
        }
        data = new StreamProxyData(proxy);
        manage.put(proxy.getProxyId(), data);
        ZLMApi ZLM_API = ZLMApiHelper.getInstance().getApi();
        // 创建拉流代理配置
        MK_INI option = ZLM_API.mk_ini_create();
        ZLM_API.mk_ini_set_option_int(option, "enable_mp4", 0);
        ZLM_API.mk_ini_set_option_int(option, "enable_audio", 0);
        ZLM_API.mk_ini_set_option_int(option, "enable_fmp4", 0);
        ZLM_API.mk_ini_set_option_int(option, "enable_ts", 0);
        ZLM_API.mk_ini_set_option_int(option, "enable_hls", 0);
        ZLM_API.mk_ini_set_option_int(option, "enable_rtsp", 1);
        ZLM_API.mk_ini_set_option_int(option, "enable_rtmp", 1);
        ZLM_API.mk_ini_set_option_int(option, "add_mute_audio", 0);
        ZLM_API.mk_ini_set_option_int(option, "auto_close", 0);
        // 创建拉流代理
        MK_PROXY_PLAYER mk_proxy = ZLM_API.mk_proxy_player_create4("__defaultVhost__", proxy.getApp(), proxy.getStream(), option, proxy.getRetryCount());
        data.setMkProxyPlayer(mk_proxy);
        // rtsp
        if (proxy.getUrl().startsWith("rtsp")) {
            // 设置代理参数 rtp_type  rtsp播放方式:RTP_TCP = 0, RTP_UDP = 1, RTP_MULTICAST = 2
            ZLM_API.mk_proxy_player_set_option(mk_proxy, "rtp_type", String.valueOf(proxy.getRtpType()));
            // 设置代理参数 protocol_timeout_ms  协议超时时间 毫秒 更多参数参见mk_proxy_player_set_option注释
            ZLM_API.mk_proxy_player_set_option(mk_proxy, "protocol_timeout_ms", String.valueOf(proxy.getTimeoutSec() * 1000));
        }

        // 开始播放代理地址
        ZLM_API.mk_proxy_player_play(mk_proxy, proxy.getUrl());
        // 销毁配置文件
        ZLM_API.mk_ini_release(option);
        //第一次代理结果获取
        IMKProxyPlayerCallBack imkProxyPlayerCallBack = new IMKProxyPlayerCallBack() {
            @Override
            public void invoke(Pointer pUser, int err, String what, int sys_err) {
                if (err == 0) {
                    System.out.println("代理播放成功");
                } else {
                    System.out.println("代理播放失败：" + what);
                }
            }
        };
        ZLM_API.mk_proxy_player_set_on_play_result(mk_proxy, imkProxyPlayerCallBack, mk_proxy.getPointer(), null);
        // 回调关闭事件
        // 添加代理关闭回调 并把代理客户端传过去释放
        ZLM_API.mk_proxy_player_set_on_close(mk_proxy, new MKProxyPlayerCallBack(this, data), mk_proxy.getPointer());
        logger.info("[开启-拉流代理] proxy_id:{} app: {} stream: {}", proxy.getProxyId(), proxy.getApp(), proxy.getStream());
    }

    public void stop(String proxyId) {
        StreamProxyData data = manage.remove(proxyId);
        if (ObjUtil.isNotNull(data)) {
            ZLMApi ZLM_API = ZLMApiHelper.getInstance().getApi();
            ZLM_API.mk_proxy_player_release(data.getMkProxyPlayer());
            logger.info("[停止-拉流代理] proxy_id:{} app: {} stream: {}", data.getProxyId(), data.getApp(), data.getStream());
        }
    }
}
